package com.google.kosmotrader;

import java.util.LinkedList;

import org.andengine.engine.camera.ZoomCamera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.LoopEntityModifier;
import org.andengine.entity.modifier.PathModifier;
import org.andengine.entity.modifier.PathModifier.IPathModifierListener;
import org.andengine.entity.modifier.PathModifier.Path;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.andengine.entity.scene.background.RepeatingSpriteBackground;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.input.touch.TouchEvent;
import org.andengine.input.touch.controller.MultiTouch;
import org.andengine.input.touch.detector.PinchZoomDetector;
import org.andengine.input.touch.detector.SurfaceScrollDetector;
import org.andengine.input.touch.detector.PinchZoomDetector.IPinchZoomDetectorListener;
import org.andengine.input.touch.detector.ScrollDetector;
import org.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.atlas.bitmap.source.AssetBitmapTextureAtlasSource;
import org.andengine.opengl.texture.bitmap.BitmapTexture.BitmapTextureFormat;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.debug.Debug;
import org.andengine.util.modifier.ease.EaseSineInOut;

import android.widget.Toast;

public class KosmoTrader extends SimpleBaseGameActivity implements IOnSceneTouchListener, IScrollDetectorListener, IPinchZoomDetectorListener{
	// ===========================================================
	// MY Fields
	// ===========================================================
    public final static int UNIVERSES_NUMBER = 1;
    public final static int GALAXIES_NUMBER = 1;
    public final static int SOLAR_SYSTEMS_IN_GALAXY_NUMBER = 1;
    //STARS_IN_SOLAR_SYSTEM_NUMBER must be square number for a while
    public final static int STARS_IN_SOLAR_SYSTEM_NUMBER = 49;
    

    public static SpaceSystem universe;
	
	// ===========================================================
	// Constants
	// ===========================================================

	private static final int CAMERA_WIDTH = 800;
	private static final int CAMERA_HEIGHT = 480;
	//private static final int SHIP_HEIGHT = 240	;
	private static final int SHIP_HEIGHT = (int) (CAMERA_HEIGHT / Math.floor(Math.sqrt(STARS_IN_SOLAR_SYSTEM_NUMBER)))	;
	//private static final int SHIP_WIDTH = 400; 
	private static final int SHIP_WIDTH = (int) (CAMERA_WIDTH / Math.floor(Math.sqrt(STARS_IN_SOLAR_SYSTEM_NUMBER)))	;
	
	

	// ===========================================================
	// Fields
	// ===========================================================

	private RepeatingSpriteBackground mGrassBackground;

	private BitmapTextureAtlas mBitmapTextureAtlas;
	private TiledTextureRegion mPlayerTextureRegion;
	
	private TiledTextureRegion  mShipTextureRegion;
	
	private ZoomCamera mZoomCamera;
	private SurfaceScrollDetector mScrollDetector;
	private PinchZoomDetector mPinchZoomDetector;
	private float mPinchZoomStartedCameraZoomFactor;
	
	AnimatedSprite player;
	Scene scene;
    public Path path;
    public Path path2;
	
	 float[] vCoordinatesX;
	 float[] vCoordinatesY;		
    

	@Override
	public EngineOptions onCreateEngineOptions() {
		this.mZoomCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

		final EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mZoomCamera);

		if(MultiTouch.isSupported(this)) {
			if(MultiTouch.isSupportedDistinct(this)) {
				Toast.makeText(this, "MultiTouch detected --> Both controls will work properly!", Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(this, "MultiTouch detected, but your device has problems distinguishing between fingers.\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();
			}
		} else {
			Toast.makeText(this, "Sorry your device does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show();
		}

		return engineOptions;

	}

	@Override
	protected void onCreateResources() {
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

		this.mGrassBackground = new RepeatingSpriteBackground(CAMERA_WIDTH, CAMERA_HEIGHT, this.getTextureManager(), AssetBitmapTextureAtlasSource.create(this.getAssets(), "gfx/stars_32_1.png"), this.getVertexBufferObjectManager());

		this.mBitmapTextureAtlas = new BitmapTextureAtlas(72, 128, BitmapTextureFormat.RGBA_4444);
		this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "spaceship_map.png", 0, 0, 3, 4);
		this.mShipTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "spaceship_map.png", 0, 0, 3, 4);
		this.mBitmapTextureAtlas.load(this.getTextureManager());
		
		
		//final ITextureRegion cardTextureRegion = this.mPlayerTextureRegion;
	}

	@Override
	protected Scene onCreateScene() {
// START MY counting
			int [] systems_numbers = {UNIVERSES_NUMBER,GALAXIES_NUMBER,SOLAR_SYSTEMS_IN_GALAXY_NUMBER,STARS_IN_SOLAR_SYSTEM_NUMBER};
			universe = new SpaceSystem(systems_numbers,CAMERA_WIDTH,CAMERA_HEIGHT,SHIP_WIDTH,SHIP_HEIGHT);

	    	
			SpaceCell cell_from =	universe.solar_system_cell.get(0, 0);
	    	//SpaceCell cell_to	=	solar_system_cell.get(5, 5);
	    	
	    	cell_from.setAsStart();		
	    //	cell_to.setAsFinish();
	   		
			// ship
	    	// SHIP_HEIGHT, SHIP_WIDTH changed intensionally!
	    	universe.setMain_ship( new Ship(1,cell_from,
					new AnimatedSprite(cell_from.getX()*SHIP_WIDTH, cell_from.getY()*SHIP_HEIGHT, SHIP_WIDTH, SHIP_HEIGHT
							, this.mShipTextureRegion, this.getVertexBufferObjectManager())
					));

Debug.d("[KTR] Ship created at from ["+universe.main_ship.getCurrent_location().getX()*SHIP_HEIGHT+";"+universe.main_ship.getCurrent_location().getY()*SHIP_WIDTH+"]");
			
	/* Counting path from finish to start - so start cell send as cell_to, finish cell - as cell_from
	and this is normal */
	//		main_ship.calc_path(solar_system_cell, cell_to,cell_from  );	
			
// END my counting		
			
			this.mEngine.registerUpdateHandler(new FPSLogger());

			scene = new Scene();
			scene.setOnAreaTouchTraversalFrontToBack();
			scene.setBackground(this.mGrassBackground);
			
			//this.mScrollDetector = new SurfaceScrollDetector(this);
			//this.mPinchZoomDetector = new PinchZoomDetector(this);

			scene.setOnSceneTouchListener(this);
			scene.setTouchAreaBindingOnActionDownEnabled(true);

			/* Create the ship image and add it to the scene. */
			player = new AnimatedSprite(0, 0, 114, 69, this.mPlayerTextureRegion, this.getVertexBufferObjectManager());

		//	scene.attachChild(player);
			scene.attachChild(universe.getMain_ship().getShip_sprite());
	//		scene.registerTouchArea(player);
			scene.registerTouchArea(universe.getMain_ship().getShip_sprite());
			scene.setTouchAreaBindingOnActionDownEnabled(true);
			
			return scene;
			
			
	}

	@Override
	public void onPinchZoomStarted(PinchZoomDetector pPinchZoomDetector,
			TouchEvent pSceneTouchEvent) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPinchZoom(PinchZoomDetector pPinchZoomDetector,
			TouchEvent pTouchEvent, float pZoomFactor) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPinchZoomFinished(PinchZoomDetector pPinchZoomDetector,
			TouchEvent pTouchEvent, float pZoomFactor) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onScrollStarted(ScrollDetector pScollDetector, int pPointerID,
			float pDistanceX, float pDistanceY) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onScroll(ScrollDetector pScollDetector, int pPointerID,
			float pDistanceX, float pDistanceY) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onScrollFinished(ScrollDetector pScollDetector, int pPointerID,
			float pDistanceX, float pDistanceY) {
		// TODO Auto-generated method stub
		
	}

	
	public void moveto (SpaceCell cell_to){
		path2 = new Path(2).to(universe.main_ship.getCurrent_location().getX()*SHIP_WIDTH, universe.main_ship.getCurrent_location().getY()*SHIP_HEIGHT).to(cell_to.getX()*SHIP_WIDTH , cell_to.getY()*SHIP_HEIGHT);

		
		
		/*animated move */
		universe.main_ship.getShip_sprite().registerEntityModifier(new PathModifier(0.5f, path2, null, new IPathModifierListener() {
			@Override
			public void onPathStarted(final PathModifier pPathModifier, final IEntity pEntity) {
				Debug.d("onPathStarted " );
				Debug.d("[KTR] Current posXY ["+universe.main_ship.getShip_sprite().getX()+";"+universe.main_ship.getShip_sprite().getY()+"]");;
			}
			@Override
			public void onPathWaypointStarted(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex) {
				Debug.d("onPathWaypointStarted:  " + pWaypointIndex);
			}
			@Override
			public void onPathWaypointFinished(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex) {
				Debug.d("onPathWaypointFinished: " + pWaypointIndex);
			}
			@Override
			public void onPathFinished(final PathModifier pPathModifier, final IEntity pEntity) {
				Debug.d("onPathFinished");
			}
		}, EaseSineInOut.getInstance())); 
	}
	
	@Override
	public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
Debug.d("[KTR] Reporting our position ["+universe.main_ship.getCurrent_location().getX()+";"+universe.main_ship.getCurrent_location().getY()+"]");
Debug.d("[KTR] Reporting our position XY ["+universe.main_ship.getCurrent_location().getX()*SHIP_HEIGHT+";"+universe.main_ship.getCurrent_location().getY()*SHIP_WIDTH+"]");

		if (pSceneTouchEvent.isActionDown()) {
		// get the nearest of Touch Cell coord
		int  x_coord = (int) Math.floor(pSceneTouchEvent.getX() / SHIP_WIDTH);
		int  y_coord = (int) Math.floor(pSceneTouchEvent.getY() / SHIP_HEIGHT);
Debug.d("[KTR] touched pos is [" +x_coord+";"+y_coord+"], [" +pSceneTouchEvent.getX()+";"+pSceneTouchEvent.getY()+"]");
				
		SpaceCell cell_to	=	universe.solar_system_cell.get(x_coord,y_coord);
		/*	
		 Counting path from finish to start - so start cell send as cell_to, finish cell - as cell_from
		and this is normal 
		*/
Debug.d("[KTR] Moving from ["+universe.main_ship.getCurrent_location().getX()+";"+universe.main_ship.getCurrent_location().getY()+"] to ["+cell_to.getX()+";"+cell_to.getY()+"]");
Debug.d("[KTR] Moving from XY ["+universe.main_ship.getCurrent_location().getX()*SHIP_HEIGHT+";"+universe.main_ship.getCurrent_location().getY()*SHIP_WIDTH+"] to ["+cell_to.getX()*SHIP_HEIGHT+";"+cell_to.getY()*SHIP_WIDTH+"]");
		

		LinkedList<SpaceCell> way_to_go = universe.calc_path(cell_to, universe.main_ship.getCurrent_location()  );


		if (!way_to_go.isEmpty()) {
			vCoordinatesX=new float[way_to_go.size()+1];
			vCoordinatesY=new float[way_to_go.size()+1];
			int i=1;
			vCoordinatesX[0]=universe.main_ship.getCurrent_location().getX()*SHIP_WIDTH;
			vCoordinatesY[0]=universe.main_ship.getCurrent_location().getY()*SHIP_HEIGHT;
			
			
			for (SpaceCell coord : way_to_go) {
Debug.d("[KTR] Next pos ["+coord.getX()+";"+coord.getY()+"]");

					vCoordinatesX[i]=coord.getX()*SHIP_WIDTH;
					vCoordinatesY[i]=coord.getY()*SHIP_HEIGHT;
					i++;
					universe.main_ship.setCurrent_location(coord);
Debug.d("[KTR] now we are at ["+universe.main_ship.getCurrent_location().getX()+";"+universe.main_ship.getCurrent_location().getY()+"]");
	
			}
			path = new Path(vCoordinatesX,vCoordinatesY);
		}
		else {
			Debug.d("[KTR] NO ROUTE");
		}

		}	
		
		universe.main_ship.getShip_sprite().registerEntityModifier(new PathModifier(0.8f, path, null, new IPathModifierListener() {
			@Override
			public void onPathStarted(final PathModifier pPathModifier, final IEntity pEntity) {
				Debug.d("onPathStarted " );
				Debug.d("[KTR] Current posXY ["+universe.main_ship.getShip_sprite().getX()+";"+universe.main_ship.getShip_sprite().getY()+"]");;
			}
			@Override
			public void onPathWaypointStarted(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex) {
				Debug.d("onPathWaypointStarted:  " + pWaypointIndex);
			}
			@Override
			public void onPathWaypointFinished(final PathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex) {
				Debug.d("onPathWaypointFinished: " + pWaypointIndex);
			}
			@Override
			public void onPathFinished(final PathModifier pPathModifier, final IEntity pEntity) {
				Debug.d("onPathFinished");
			}
		}, EaseSineInOut.getInstance())); 
		

		return false;
	}

	

}


